package com.stu.aq;

import android.content.Context;
import android.graphics.Color;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;

import com.stu.widget.*;

public class NumberEntryPopup implements View.OnTouchListener {
	private EditText value;
	private String original;
	private PopupWindow w;
	private EntryButton minus, decimal, delete;
	private boolean firstPressed, integerOnly;
	private final static int MINUS=11, DECIMAL=12, CANCEL=13, DONE=14, DELETE=15;

	public interface NumberEntryListener {
		public void OnDone( EditText v );
	}
	private NumberEntryListener l;

	public NumberEntryPopup( Context c ) {
		// convert dp to px
		int margin = (int)TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 15f, c.getResources().getDisplayMetrics() );
		// do the layout programatically to better control alignment
		RelativeLayout view = new RelativeLayout( c );
		RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT );
		view.setLayoutParams( lp );
		view.setBackgroundColor( Color.rgb(128, 128, 128) );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.setMargins( margin, 0, 0, 0 );
		EntryButton b = new EntryButton( c );
		b.setText( "1" );
		b.setId( 1 );
		b.setOnTouchListener( this );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "2" );
		b.setId( 2 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, 1 );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "3" );
		b.setId( 3 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, 2 );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "4" );
		b.setId( 4 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.setMargins( margin, 0, 0, 0 );
		lp.addRule( RelativeLayout.BELOW, 1 );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "5" );
		b.setId( 5 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, 4 );
		lp.addRule( RelativeLayout.BELOW, 2 );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "6" );
		b.setId( 6 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, 5 );
		lp.addRule( RelativeLayout.BELOW, 3 );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "7" );
		b.setId( 7 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.setMargins( margin, 0, 0, 0 );
		lp.addRule( RelativeLayout.BELOW, 4 );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "8" );
		b.setId( 8 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, 7 );
		lp.addRule( RelativeLayout.BELOW, 5 );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setText( "9" );
		b.setId( 9 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, 8 );
		lp.addRule( RelativeLayout.BELOW, 6 );
		view.addView( b, lp );
		minus = new EntryButton( c );
		minus.setText( "-" );
		minus.setId( MINUS );
		minus.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.setMargins( margin, 0, 0, 0 );
		lp.addRule( RelativeLayout.BELOW, 7 );
		view.addView( minus, lp );
		b = new EntryButton( c );
		b.setText( "0" );
		b.setId( 10 );
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, MINUS );
		lp.addRule( RelativeLayout.BELOW, 8 );
		view.addView( b, lp );
		decimal = new EntryButton( c );
		decimal.setText( "." );
		decimal.setId( DECIMAL );
		decimal.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, 10 );
		lp.addRule( RelativeLayout.BELOW, 9 );
		view.addView( decimal, lp );
		b = new EntryButton( c );
		b.setId( CANCEL );
		b.setCancelButton();
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.BELOW, MINUS );
		view.addView( b, lp );
		b = new EntryButton( c );
		b.setId( DONE );
		b.setDoneButton();
		b.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, CANCEL );
		lp.addRule( RelativeLayout.BELOW, 10 );
		view.addView( b, lp );
		delete = new EntryButton( c );
		delete.setId( DELETE );
		delete.setDeleteButton( c );
		delete.setOnTouchListener( this );
		lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
		lp.addRule( RelativeLayout.RIGHT_OF, DONE );
		lp.addRule( RelativeLayout.BELOW, DECIMAL );
		view.addView( delete, lp );
		w = new PopupWindow( view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
	}
	
	/**
	 * Display the number entry popup
	 * @param parent Parent view for the popup
	 * @param val EditText of the current and resulting value
	 * @param l Callback when Done
	 * @param integerOnly Allow only positive integer values
	 */
	public void show( View parent, EditText val, NumberEntryListener l, boolean integerOnly ) {
		this.integerOnly= integerOnly; 
		firstPressed = true;
		this.l = l;
		value = val;
		original = value.getText().toString();
		if( integerOnly ) {
			minus.setState( EntryButton.State.DISABLED );
			decimal.setState( EntryButton.State.DISABLED );
		} else {
			minus.setState( (original.indexOf('-') == -1) ? EntryButton.State.NORMAL : EntryButton.State.DISABLED );
			decimal.setState( (original.indexOf('.') == -1) ? EntryButton.State.NORMAL : EntryButton.State.DISABLED );
		}
		delete.setState( (original.length() != 0) ? EntryButton.State.NORMAL : EntryButton.State.DISABLED );
		val.selectAll();
		w.showAtLocation( parent, Gravity.CENTER, 0, 0 );
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if( l == null )
			return true;

		if( ((EntryButton)v).getState() == EntryButton.State.DISABLED )
			return true;

		if( event.getActionMasked() == MotionEvent.ACTION_DOWN ) {
			((EntryButton)v).setState( EntryButton.State.PRESSED );
			return true;
		}

		if( v.getId() == CANCEL ) {
			((EntryButton)v).setState( EntryButton.State.NORMAL );
			value.setText( original );
			w.dismiss();
			l.OnDone( value );
			return true;
		}

		if( v.getId() == DONE ) {
			((EntryButton)v).setState( EntryButton.State.NORMAL );
			w.dismiss();
			l.OnDone( value );
			return true;
		}

		if( firstPressed ) {
			if( v.getId() != DELETE )
				value.getText().clear();
			firstPressed = false;
		}

		switch( v.getId() ) {
			case 1:
				value.getText().append('1');
				break;
			case 2:
				value.getText().append('2');
				break;
			case 3:
				value.getText().append('3');
				break;
			case 4:
				value.getText().append('4');
				break;
			case 5:
				value.getText().append('5');
				break;
			case 6:
				value.getText().append('6');
				break;
			case 7:
				value.getText().append('7');
				break;
			case 8:
				value.getText().append('8');
				break;
			case 9:
				value.getText().append('9');
				break;
			case 10:
				value.getText().append('0');
				break;
			case DECIMAL:
				value.getText().append( '.' );
				break;
			case MINUS:
				value.getText().insert( 0, "-" );
				break;
			case DELETE:
				int len = value.length();
				if( len > 0 )
					value.getText().delete( len-1, len );
				break;
		}
		String s = value.getText().toString();
		if( !integerOnly ) {
			minus.setState( (s.indexOf('-') == -1) ? EntryButton.State.NORMAL : EntryButton.State.DISABLED );
			decimal.setState( (s.indexOf('.') == -1) ? EntryButton.State.NORMAL : EntryButton.State.DISABLED );
		}
		delete.setState( (s.length() != 0) ? EntryButton.State.NORMAL : EntryButton.State.DISABLED );
		if( v.getId() >= 1 && v.getId() <= 10 )
			((EntryButton)v).setState( EntryButton.State.NORMAL );
		return true;
	}
}
